Modification start date
[BattleCats.git] / Assets / Scripts / Imported / Tilemap / Brushes / Line Brush / Scripts / Editor / LineBrush.cs
blob3b1f3b06749e112738e62e5db85e5ff139aaf7bd
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using UnityEngine;
5 using UnityEngine.Tilemaps;
6 using System.Linq;
8 namespace UnityEditor
10 [CustomGridBrush(true, false, false, "Line Brush")]
11 public class LineBrush : GridBrush
13 public bool lineStartActive = false;
14 public bool fillGaps = false;
15 public Vector3Int lineStart = Vector3Int.zero;
17 public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
19 if (lineStartActive)
21 Vector2Int startPos = new Vector2Int(lineStart.x, lineStart.y);
22 Vector2Int endPos = new Vector2Int(position.x, position.y);
23 if (startPos == endPos)
24 base.Paint(grid, brushTarget, position);
25 else
27 foreach (var point in GetPointsOnLine(startPos, endPos, fillGaps))
29 Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
30 base.Paint(grid, brushTarget, paintPos);
33 lineStartActive = false;
35 else
37 lineStart = position;
38 lineStartActive = true;
42 [MenuItem("Assets/Create/Line Brush")]
43 public static void CreateBrush()
45 string path = EditorUtility.SaveFilePanelInProject("Save Line Brush", "New Line Brush", "asset", "Save Line Brush", "Assets");
47 if (path == "")
48 return;
50 AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<LineBrush>(), path);
53 /// <summary>
54 /// Added option to fill gaps for continuous lines.
55 /// </summary>
56 public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int startPos, Vector2Int endPos, bool fillGaps)
58 var points = GetPointsOnLine(startPos, endPos);
59 if (fillGaps)
61 var rise = endPos.y - startPos.y;
62 var run = endPos.x - startPos.x;
64 if (rise != 0 || run != 0)
66 var extraStart = startPos;
67 var extraEnd = endPos;
70 if (Mathf.Abs(rise) >= Mathf.Abs(run))
72 // up
73 if (rise > 0)
75 extraStart.y += 1;
76 extraEnd.y += 1;
78 // down
79 else // rise < 0
82 extraStart.y -= 1;
83 extraEnd.y -= 1;
86 else // Mathf.Abs(rise) < Mathf.Abs(run)
89 // right
90 if (run > 0)
92 extraStart.x += 1;
93 extraEnd.x += 1;
95 // left
96 else // run < 0
98 extraStart.x -= 1;
99 extraEnd.x -= 1;
103 var extraPoints = GetPointsOnLine(extraStart, extraEnd);
104 extraPoints = extraPoints.Except(new[] { extraEnd });
105 points = points.Union(extraPoints);
110 return points;
113 // http://ericw.ca/notes/bresenhams-line-algorithm-in-csharp.html
114 public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int p1, Vector2Int p2)
116 int x0 = p1.x;
117 int y0 = p1.y;
118 int x1 = p2.x;
119 int y1 = p2.y;
121 bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
122 if (steep)
124 int t;
125 t = x0; // swap x0 and y0
126 x0 = y0;
127 y0 = t;
128 t = x1; // swap x1 and y1
129 x1 = y1;
130 y1 = t;
132 if (x0 > x1)
134 int t;
135 t = x0; // swap x0 and x1
136 x0 = x1;
137 x1 = t;
138 t = y0; // swap y0 and y1
139 y0 = y1;
140 y1 = t;
142 int dx = x1 - x0;
143 int dy = Math.Abs(y1 - y0);
144 int error = dx / 2;
145 int ystep = (y0 < y1) ? 1 : -1;
146 int y = y0;
147 for (int x = x0; x <= x1; x++)
149 yield return new Vector2Int((steep ? y : x), (steep ? x : y));
150 error = error - dy;
151 if (error < 0)
153 y += ystep;
154 error += dx;
157 yield break;
161 [CustomEditor(typeof(LineBrush))]
162 public class LineBrushEditor : GridBrushEditor
164 private LineBrush lineBrush { get { return target as LineBrush; } }
165 private Tilemap lastTilemap;
167 public override void OnPaintSceneGUI(GridLayout grid, GameObject brushTarget, BoundsInt position, GridBrushBase.Tool tool, bool executing)
169 base.OnPaintSceneGUI(grid, brushTarget, position, tool, executing);
170 if (lineBrush.lineStartActive)
172 Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
173 if (tilemap != null)
174 lastTilemap = tilemap;
176 // Draw preview tiles for tilemap
177 Vector2Int startPos = new Vector2Int(lineBrush.lineStart.x, lineBrush.lineStart.y);
178 Vector2Int endPos = new Vector2Int(position.x, position.y);
179 if (startPos == endPos)
180 PaintPreview(grid, brushTarget, position.min);
181 else
183 foreach (var point in LineBrush.GetPointsOnLine(startPos, endPos, lineBrush.fillGaps))
185 Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
186 PaintPreview(grid, brushTarget, paintPos);
190 if (Event.current.type == EventType.Repaint)
192 var min = lineBrush.lineStart;
193 var max = lineBrush.lineStart + position.size;
195 // Draws a box on the picked starting position
196 GL.PushMatrix();
197 GL.MultMatrix(GUI.matrix);
198 GL.Begin(GL.LINES);
199 Handles.color = Color.blue;
200 Handles.DrawLine(new Vector3(min.x, min.y, min.z), new Vector3(max.x, min.y, min.z));
201 Handles.DrawLine(new Vector3(max.x, min.y, min.z), new Vector3(max.x, max.y, min.z));
202 Handles.DrawLine(new Vector3(max.x, max.y, min.z), new Vector3(min.x, max.y, min.z));
203 Handles.DrawLine(new Vector3(min.x, max.y, min.z), new Vector3(min.x, min.y, min.z));
204 GL.End();
205 GL.PopMatrix();
210 public override void ClearPreview()
212 base.ClearPreview();
213 if (lastTilemap != null)
215 lastTilemap.ClearAllEditorPreviewTiles();
216 lastTilemap = null;